import React, { FC, memo, ReactNode, useContext, useEffect } from 'react'
import classNames from 'classnames'
import { FormContext } from './form'
import useStore, { CustomRule } from './useStore'
// export type SomeRequired<T, K extends keyof T> = Required<Pick<T, K>> & Omit<T, K>
export interface FormItemProps {
  name: string // 字段名
  label?: string
  children?: ReactNode
  valuePropName?: string // 值的属性，如 checkbox 的是 'checked'
  trigger?: string // 设置收集字段值变更的时机
  getValueFromEvent?: (event: any) => any // 设置如何将 event 的值转换成字段值
  rules?: CustomRule[] // 校验规则，设置字段的校验逻辑。请看 async validator 了解更多规则
  validateTrigger?: string // 设置字段校验的时机
}
const configWarnTip = (list: any[]) => {
  // 如果没有子元素，则报错
  if (list.length === 0) {
    console.error('No child element found in Form.Item, please provide one form component')
  }
  // 子元素只能有一个
  if (list.length > 1) {
    console.warn('Only support one child element in Form.Item, others will be omitted')
  }
  // 不是 react element，则报错
  if (!React.isValidElement(list[0])) {
    console.error('Child component is not a valid React Element')
  }
}
export const FormItem = (props: FormItemProps) => {
  const {
    label,
    children,
    name, // 字段名 校验使用
    valuePropName = 'value',
    trigger = 'onChange', // 默认事件
    validateTrigger = 'onBlur', // 默认触发规则的事件
    getValueFromEvent = (e) => e.target.value,
    rules
  } = props
  const { initialValues, dispatch, fields, validateField } = useContext(FormContext)
  // const { dispatch, fields, validateField } = useStore()
  // console.log('0context dispatch', dispatch)
  // console.log('context fields', fields, '')
  // console.log('context initialValues', initialValues, '')
  // console.log('context validateField', validateField, '')
  useEffect(() => {
    const initVal = (initialValues && initialValues[name]) || '' // 初始值
    dispatch({
      type: 'addField',
      name,
      value: {
        label,
        name,
        value: initVal, // 初始值
        rules: rules || [],
        errors: [],
        isValid: true // 初始值是有效的
      }
    })
  }, [])
  const fieldState = fields[name] // 当前字段的状态
  const value = fieldState && fieldState.value // 字段的值，如果设置 initialValues 会有初始值
  const errors = fieldState && fieldState.errors // 错误信息
  const hasError = errors && errors.length > 0 // 是否有错误信息
  const isRequired = rules?.some((rule) => typeof rule !== 'function' && rule.required) // 是否必填项
  // console.log('当前', fieldState, '-', value)

  // 1 手动的创建属性列表
  const controlProps: Record<string, any> = {}
  controlProps[valuePropName] = value || '' // 将值设置到节点上，如input checked
  if (rules) {
    controlProps[validateTrigger] = async () => {
      await validateField(name) // 默认事件 onBlur 失去焦点校验
    }
  }
  // 默认事件 onChange
  controlProps[trigger] = (e: React.ChangeEvent<HTMLElement>) => {
    const value = getValueFromEvent(e) // 获取值
    dispatch({ type: 'updateValue', name, value }) // 更新 value
  }
  // 2 获取 children 数组的第一个元素
  const childList = React.Children.toArray(children) // 转换数组
  const child = childList[0] as React.ReactElement
  configWarnTip(childList) // 配置警告
  // 3 cloneElement，混合这个child 以及 手动的属性列表
  const childNode = React.cloneElement(child, {
    // ...child.props,
    ...controlProps // 将值传递
  })
  return (
    <div className={classNames('dog-row', { 'dog-row-no-label': !label })}>
      {label && (
        <div className="dog-form-item-label">
          <label title={label} className={classNames({ 'dog-form-item-required': isRequired })}>
            {label}
          </label>
        </div>
      )}
      <div className="dog-form-item">
        <div
          className={classNames('dog-form-item-control', {
            // 'dog-form-item-has-error': hasError
          })}
        >
          {childNode}
        </div>
        {hasError && (
          <div className="dog-form-item-explain">
            <span>{errors[0].message}</span>
          </div>
        )}
      </div>
    </div>
  )
}

export default memo(FormItem)
